﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MessageQuque.Common
{
    /// <summary>
    /// 提供类型转换扩展方法
    /// </summary>
    public static class ConvertExtensions
    {

        /// <summary>
        /// 尝试将对象转换为指定的类型
        /// </summary>
        /// <typeparam name="T">要转换的目标类型</typeparam>
        /// <param name="value">要转换的对象</param>
        /// <returns>转换后的结果,转换不成功返回类型默认值</returns>
        public static T CastTo<T>(this object value, T defaultValue = default(T))
        {
            if (Convertor<T>.castMethod != null)
            {
                try
                {
                    return Convertor<T>.castMethod(value.ToString());
                }
                catch (Exception ex)
                {
                    Logger.Error(ex.Message, ex);
                    Logger.Error(ex.InnerException.Message, ex.InnerException);
                    return defaultValue;
                }
            }

            return default(T);
        }
        public static T CastTo<T>(this object value)
        {
            if (Convertor<T>.castMethod != null)
            {
                try
                {
                    return Convertor<T>.castMethod(value.ToString());
                }
                catch (Exception ex)
                {
                    Logger.Error(ex.Message, ex);
                    Logger.Error(ex.InnerException.Message, ex.InnerException);
                }
            }

            return default(T);
        }
        /// <summary>
        /// 对象间的转换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T CastAs<T>(this object value)
        {
            var result = default(T);

            result = value.ToJsonSerialize().DeserializeFromJson<T>();

            if (null == result)
                result = default(T);

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="values"></param>
        /// <param name="separator"></param>
        /// <returns></returns>
        public static T[] Split<T>(this string values, char[] separator = null)
        {
            if (string.IsNullOrWhiteSpace(values))
                return default(T[]);

            if (null == separator)
                separator = new char[] { ',', ';' };

            var array = values.Split(separator, StringSplitOptions.RemoveEmptyEntries).Distinct();

            var result = new List<T>();

            foreach (var item in array)
            {
                result.Add(item.CastTo<T>());
            }

            return result.ToArray();
        }
        /// <summary>
        /// 去掉数组中的null项。
        /// </summary>
        /// <param name="thisArray"></param>
        /// <returns></returns>
        public static IList<int> TrimNull(this int?[] thisArray)
        {
            var result = new List<int>();
            foreach (var item in thisArray)
            {
                if (item.HasValue)
                    result.Add(item.Value);
            }
            return result;
        }

        /// <summary>
        /// 定义转换委托
        /// </summary>
        static ConvertExtensions()
        {
            Convertor<short>.castMethod = short.Parse;
            Convertor<int>.castMethod = int.Parse;
            Convertor<long>.castMethod = long.Parse;
            Convertor<byte>.castMethod = byte.Parse;
            Convertor<ushort>.castMethod = ushort.Parse;
            Convertor<uint>.castMethod = uint.Parse;
            Convertor<ulong>.castMethod = ulong.Parse;
            Convertor<sbyte>.castMethod = sbyte.Parse;
            Convertor<float>.castMethod = float.Parse;
            Convertor<double>.castMethod = double.Parse;
            Convertor<decimal>.castMethod = decimal.Parse;
            Convertor<bool>.castMethod = bool.Parse;
            Convertor<DateTime>.castMethod = DateTime.Parse;
            Convertor<string>.castMethod = Convert.ToString;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        private class Convertor<T>
        {
            public static Func<string, T> castMethod;
        }

        /// <summary>
        /// 若值是 null 则使用指定值代换
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="value">原始值</param>
        /// <param name="defaultValue">当值为 null 时用于代换的默认值</param>
        /// <returns>原始值，当原始值不为 null 或 DBbNull，否则使用代换的默认值</returns>
        public static T IfNull<T>(this T value, T defaultValue)
        {
            if (value == null || Convert.IsDBNull(value))
                return defaultValue;
            else
                return value;
        }

        /// <summary>
        /// 若值是 null 则使用指定值代换
        /// </summary>
        /// <param name="value">原始值</param>
        /// <param name="defaultValue">当值为 null 时用于代换的默认值</param>
        /// <returns>当原始值不为 null 或 DBbNull，返回原始值，否则返回代换的默认值</returns>
        public static object IfNull(this object value, object defaultValue)
        {
            if (value == null || Convert.IsDBNull(value))
                return defaultValue;
            else
                return value;
        }


        /// <summary>
        /// 若值是 null 则使用指定值代换
        /// </summary>
        /// <typeparam name="TInput">值类型</typeparam>
        /// <typeparam name="TOut">输出值类型</typeparam>
        /// <param name="value">原始值</param>
        /// <param name="defaultValue">当值为 null 时用于代换的默认值</param>
        /// <param name="converter">当值不为空时，对值进行类型转换的转换器。</param>
        /// <returns>当原始值不为 null 或 DBbNull，返回转换后的原始值，否则返回代换的默认值</returns>
        public static TOut IfNull<TInput, TOut>(this TInput value, TOut defaultValue, Func<TInput, TOut> converter)
        {
            if (value == null || Convert.IsDBNull(value))
                return defaultValue;

            else
            {
                if (converter == null)
                    throw new ArgumentNullException("converter");

                return converter(value);
            }
        }



        /// <summary>
        /// 将对象所有属性转换为对象图
        /// </summary>
        /// <param name="obj">要转换为对象图的对象</param>
        /// <returns>对象图</returns>
        public static IDictionary<string, string> ToPropertiesMap(this object obj)
        {
            if (obj == null)
                return null;

            var dictionary = new Dictionary<string, string>();

            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(obj))
            {
                var key = property.Name;
                var _value = property.GetValue(obj);

                string value = null;

                if (_value != null)
                    value = _value.ToString();

                dictionary.Add(key, value);
            }

            return dictionary;
        }


    }
}
